﻿// -----------------------------------------------------------------------
// Copyright (c) David Kean. All rights reserved.
// -----------------------------------------------------------------------
extern alias pcl;
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using AsyncOperation = pcl::System.ComponentModel.AsyncOperation;
using AsyncOperationManager = pcl::System.ComponentModel.AsyncOperationManager;
using System.Threading;

namespace Portable.ComponentModel
{
    [TestClass]
    public class AsyncOperationManagerTests
    {
        [TestMethod]
        public void CreateOperation1_NullAsUserSuppliedState_SetsReturnedAsyncOperationUserSuppliedStateToNull()
        {
            var operation = AsyncOperationManager.CreateOperation((object)null);

            Assert.IsNull(operation.UserSuppliedState);
        }

        [TestMethod]
        public void CreateOperation2_NullAsUserSuppliedState_SetsReturnedAsyncOperationUserSuppliedStateToNull()
        {
            var operation = AsyncOperationManager.CreateOperation((SynchronizationContext)null, (object)null);

            Assert.IsNull(operation.UserSuppliedState);
        }

        [TestMethod]
        public void CreateOperation1_ValueAsUserSuppliedState_SetsReturnedAsyncOperationUserSuppliedState()
        {
            var value = new object();
            var operation = AsyncOperationManager.CreateOperation(value);

            Assert.AreEqual(value, operation.UserSuppliedState);
        }

        [TestMethod]
        public void CreateOperation2_ValueAsUserSuppliedState_SetsReturnedAsyncOperationUserSuppliedState()
        {
            var value = new object();
            var operation = AsyncOperationManager.CreateOperation((SynchronizationContext)null, value);

            Assert.AreEqual(value, operation.UserSuppliedState);
        }

        [TestMethod]
        public void CreateOperation1_SetsReturnedAsyncOperationSynchronizationToCurrent()
        {
            var context = SynchronizationContextFactory.Create();
            SynchronizationContext.SetSynchronizationContext(context);

            var operation = AsyncOperationManager.CreateOperation((object)null);

            Assert.AreEqual(context, operation.SynchronizationContext);
        }

        [TestMethod]
        public void CreateOperation1_WhenCurrentNull_SetsReturnedAsyncOperationSynchronizationToNewContext()
        {
            SynchronizationContext.SetSynchronizationContext(null);

            var operation = AsyncOperationManager.CreateOperation((object)null);

            Assert.AreEqual(typeof(SynchronizationContext), operation.SynchronizationContext.GetType());
        }

        [TestMethod]
        public void CreateOperation2_NullAsSynchronizationContext_SetsReturnedAsyncOperationSynchronizationToCurrent()
        {
            var context = SynchronizationContextFactory.Create();
            SynchronizationContext.SetSynchronizationContext(context);

            var operation = AsyncOperationManager.CreateOperation((SynchronizationContext)null, (object)null);

            Assert.AreEqual(context, operation.SynchronizationContext);
        }

        [TestMethod]
        public void CreateOperation2_NullAsSynchronizationContext_WhenCurrentNull_SetsReturnedAsyncOperationSynchronizationToNewContext()
        {
            SynchronizationContext.SetSynchronizationContext(null);

            var operation = AsyncOperationManager.CreateOperation((SynchronizationContext)null, (object)null);

            Assert.AreEqual(typeof(SynchronizationContext), operation.SynchronizationContext.GetType());
        }

        [TestMethod]
        public void CreateOperation2_ValueAsSynchronizationContext_SetsReturnedAsyncOperationSynchronization()
        {
            var value = SynchronizationContextFactory.Create();

            var operation = AsyncOperationManager.CreateOperation(value, (object)null);

            Assert.AreEqual(value, operation.SynchronizationContext);
        }

        [TestMethod]
        public void CreateOperation1_CallsSynchronizationContextOperationStarted()
        {
            int callCount = 0;
            var context = SynchronizationContextFactory.OverrideOperationStarted(() => callCount++);
            SynchronizationContext.SetSynchronizationContext(context);

            var operation = AsyncOperationManager.CreateOperation((object)null);

            Assert.AreEqual(1, callCount);
        }

        [TestMethod]
        public void CreateOperation2_CallsSynchronizationContextOperationStarted()
        {
            int callCount = 0;
            var context = SynchronizationContextFactory.OverrideOperationStarted(() => callCount++);

            var operation = AsyncOperationManager.CreateOperation(context, (object)null);

            Assert.AreEqual(1, callCount);
        }
    }
}
